package org.intrasearch.core;

import com.google.inject.Singleton;
import org.intrasearch.core.collections.BigMap;
import org.intrasearch.core.io.SerializationBuilder;
import org.intrasearch.core.io.SerializationConfig;
import org.intrasearch.core.io.StringExternalizableProvider;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;

@Singleton
public class InvertedIndexImpl implements InvertedIndex
{
    private final Map<String, InvertedIndexArtifactIdCollection> index;

    public InvertedIndexImpl()
    {
        try
        {
            index = new BigMap<String, InvertedIndexArtifactIdCollection>(File.createTempFile("inverted","index"), (int) Math.pow(2,24), new SerializationConfig()
            {
                public void configure(SerializationBuilder builder)
                {
                    builder.addClass(ArtifactId.class);
                    builder.addClass(InvertedIndexArtifactIdCollection.class);
                    builder.addExternalizableProvider(String.class, new StringExternalizableProvider());
                }
            });
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }
    }

    InvertedIndexImpl(Map<String, InvertedIndexArtifactIdCollection> index)
    {
        this.index = index;
    }

    public void put(String word, Collection<ArtifactId> artifactIds)
    {
        word = word.toLowerCase();
        InvertedIndexArtifactIdCollection newCollection = new InvertedIndexArtifactIdCollection(artifactIds);
        InvertedIndexArtifactIdCollection artifactIdCollection = index.get(word);
        if (artifactIdCollection != null)
        {
            newCollection = artifactIdCollection.merge(newCollection);
        }
        index.put(word, newCollection);
    }

    public Collection<ArtifactId> artifactsByWord(String word)
    {
        word = word.toLowerCase();
        InvertedIndexArtifactIdCollection collection = index.get(word);
        if (collection == null)
        {
            return Collections.emptyList();
        }
        return collection.getArtifactIds();
    }

    public void flush()
    {
        if (!(index instanceof BigMap))
        {
            return;
        }
        BigMap bigMap = (BigMap) index;
        bigMap.flush();
    }
}
